Namespace.Use("UI.Theme.Button", function(ns) {
    //  Imports.
    var UI = Namespace.Import("UI");

    var RenderLabeledButton = Polymorphic.Create(
        [CanvasRenderingContext2D, Number, Number, String, String, Boolean, Number],
        function(ctx, width, height, text, font, is_default, state) {
            var radius = 3;
            var padding = 2;
            var enabled = this.AccessEnabled();

            //  Clear the canvas.
            ctx.clearRect(0, 0, width, height);

            //  Draw the background.
            ctx.lineWidth = 1;
            if (state == UI.Object.CanvasButton.STATE_UP || !enabled) {
                if (is_default == true) {
                    ctx.strokeStyle = "rgba(128,128,128,1)";
                } else {
                    ctx.strokeStyle = "rgba(211,211,211,1)";
                }
                ctx.fillStyle = "rgba(234,234,234,1)";
            } else if (state == UI.Object.CanvasButton.STATE_OVER) {
                if (is_default == true) {
                    ctx.strokeStyle = "rgba(96,96,96,1)";
                } else {
                    ctx.strokeStyle = "rgba(178,178,178,1)";
                }
                ctx.fillStyle = "rgba(234,234,234,1)";
            } else {
                if (is_default == true) {
                    ctx.strokeStyle = "rgba(96,96,96,1)";
                } else {
                    ctx.strokeStyle = "rgba(178,178,178,1)";
                }
                ctx.fillStyle = "rgba(242,242,242,1)";
            }
            ctx.beginPath();
            ctx.moveTo(radius + padding, padding);
            ctx.lineTo(width - radius - padding, padding);
            ctx.arcTo(width - padding, padding, width - padding, padding + radius, radius);
            ctx.lineTo(width - padding, radius + padding, width - padding, height - radius - padding);
            ctx.arcTo(width - padding, height - padding, width - radius - padding, height - padding, radius);
            ctx.lineTo(padding + radius, height - padding);
            ctx.arcTo(padding, height - padding, padding, height - radius - padding, radius);
            ctx.lineTo(padding, radius + padding);
            ctx.arcTo(padding, padding, padding + radius, padding, radius);
            ctx.closePath();
            ctx.fill();
            ctx.stroke();

            //  Draw the text.
            if (!enabled) {
                ctx.fillStyle = "rgba(164,164,164,1)";
            } else if (state == UI.Object.CanvasButton.STATE_UP) {
                ctx.fillStyle = "rgba(114,114,114,1)";
            } else if (state == UI.Object.CanvasButton.STATE_OVER) {
                ctx.fillStyle = "rgba(76,76,76,1)";
            } else {
                ctx.fillStyle = "rgba(58,58,58,1)";
            }
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.font = font;
            if (ctx.measureText(text).width > width - padding - ctx.lineWidth) {
                while(text.length > 0 && ctx.measureText(text + "...").width > width - padding - ctx.lineWidth) {
                    text = text.substring(0, text.length - 1);
                }
                text = text + "...";
            }
            ctx.fillText(text, width / 2, height / 2);
        }
    );

    //  Export public APIs.
    Namespace.Export(ns, "RenderLabeledButton", RenderLabeledButton);
});